﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;

namespace WakeupOnLan.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class StartController : ControllerBase
    {
        const string macCheckRegexString = @"^([0-9a-fA-F]{2})(([/\s:-][0-9a-fA-F]{2}){5})$";

        private static readonly Regex MacCheckRegex = new Regex(macCheckRegexString);
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly ILogger<StartController> _logger;
        private readonly IConfiguration _configuration;
        public StartController(ILogger<StartController> logger,IConfiguration configuration)
        {
            _logger = logger;
            _configuration = configuration;
        }

        [HttpGet]
        public JsonResult Get()
        {
            string macAddress = !string.IsNullOrEmpty(_configuration["MacAddress"])
                ? _configuration["MacAddress"]
                : "B0-6E-BF-C3-8D-55";
           var result = WakeUp(macAddress);
            return new JsonResult(result);
        }

        public void SendMagicPacket(string macAddress, int port = 9)
        {
            string ip = "255.255.255.255";
            string magicPacage = "0xFFFFFFFFFFFF";
            string tempMacAddress = "";
            if (!string.IsNullOrEmpty(macAddress) && (macAddress.Length == 17 || macAddress.Length == 12))
            {
                tempMacAddress = macAddress.Replace("-", "").Replace(":", "");
                for (int i = 0; i < 16; i++)
                {
                    magicPacage = magicPacage + tempMacAddress;
                }

                byte[] packet = hexToBinary(magicPacage);
                try
                {
                    IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(ip), port);
                    UdpClient client = new UdpClient(new IPEndPoint(IPAddress.Any, 0));
                    client.Send(packet, packet.Length,endPoint);
                    
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    throw;
                }
                finally
                {
                    
                }
            }


        }

        private static byte[] hexToBinary(string package)
        {
            byte[] resultBytes = new byte[package.Length];
            package = package.Replace("0x", "").ToUpper();
            resultBytes = Encoding.Default.GetBytes(package);
            return resultBytes;
        }

        //唤醒主要逻辑方法
        public static bool WakeUp(string mac)
        {
            //查看该MAC地址是否匹配正则表达式定义，（mac，0）前一个参数是指mac地址，后一个是从指定位置开始查询，0即从头开始
            if (MacCheckRegex.IsMatch(mac, 0))
            {
                byte[] macByte = FormatMac(mac);
                WakeUpCore(macByte);
                return true;
            }

            return false;

        }

        private static void WakeUpCore(byte[] mac)
        {
            //发送方法是通过UDP
            UdpClient client = new UdpClient();
            //Broadcast内容为：255,255,255,255.广播形式，所以不需要IP
            client.Connect(System.Net.IPAddress.Broadcast, 50000);
            //下方为发送内容的编制，6遍“FF”+17遍mac的byte类型字节。
            byte[] packet = new byte[17 * 6];
            for (int i = 0; i < 6; i++)
                packet[i] = 0xFF;
            for (int i = 1; i <= 16; i++)
            for (int j = 0; j < 6; j++)
                packet[i * 6 + j] = mac[j];
            //唤醒动作
            int result = client.Send(packet, packet.Length);
        }

        private static byte[] FormatMac(string macInput)
        {
            byte[] mac = new byte[6];

            string str = macInput;
            //消除MAC地址中的“-”符号
            string[] sArray = str.Split('-');


            //mac地址从string转换成byte
            for (var i = 0; i < 6; i++)
            {
                var byteValue = Convert.ToByte(sArray[i], 16);
                mac[i] = byteValue;
            }

            return mac;
        }
    }
}
